from rest_framework import serializers

from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes

from django.conf import settings
from django.core.files.storage import default_storage

from baserow.core.models import UserFile
from baserow.core.user_files.handler import UserFileHandler


class UserFileUploadViaURLRequestSerializer(serializers.Serializer):
    url = serializers.URLField()


class UserFileURLAndThumbnailsSerializerMixin(serializers.Serializer):
    url = serializers.SerializerMethodField()
    thumbnails = serializers.SerializerMethodField()

    def get_instance_attr(self, instance, name):
        return getattr(instance, name)

    @extend_schema_field(OpenApiTypes.URI)
    def get_url(self, instance):
        name = self.get_instance_attr(instance, "name")
        path = UserFileHandler().user_file_path(name)
        url = default_storage.url(path)
        return url

    @extend_schema_field(OpenApiTypes.OBJECT)
    def get_thumbnails(self, instance):
        if not self.get_instance_attr(instance, "is_image"):
            return None

        name = self.get_instance_attr(instance, "name")

        return {
            thumbnail_name: {
                "url": default_storage.url(
                    UserFileHandler().user_file_thumbnail_path(name, thumbnail_name)
                ),
                "width": size[0],
                "height": size[1],
            }
            for thumbnail_name, size in settings.USER_THUMBNAILS.items()
        }


class UserFileSerializer(
    UserFileURLAndThumbnailsSerializerMixin, serializers.ModelSerializer
):
    name = serializers.SerializerMethodField()

    class Meta:
        model = UserFile
        fields = (
            "size",
            "mime_type",
            "is_image",
            "image_width",
            "image_height",
            "uploaded_at",
            "url",
            "thumbnails",
            "name",
            "original_name",
        )

    @extend_schema_field(OpenApiTypes.STR)
    def get_name(self, instance):
        return instance.name
